package com.wy.framework.services.common;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wy.framework.constants.DBConstant;
import com.wy.framework.constants.RtnCodeConstant;
import com.wy.framework.exceptions.ServiceException;
import com.wy.framework.services.AbstractBaseService;


public class FileService extends AbstractBaseService {
    private static Logger logger = LoggerFactory.getLogger(FileService.class);

    /**
     * 获取允许上传文件最大大小
     */
	public Integer getMaxSize() throws ServiceException {
		String maxSize = querySysConfigById(DBConstant.SYS_CONFIG_UPLOAD_FILE_MAX_SIZE);
		// 数据库保存以KB为单位,这里转换为Byte
		Integer integer = Integer.parseInt(maxSize) * 1024;
		return integer;
	}

	public String maxSizeCheck(String error) {
		if (error.startsWith("the request was rejected because its size")) {
			int start = error.indexOf("maximum (") + "maximum (".length();
			String maxSize = error.substring(start, error.length() - 1);
			return new DecimalFormat("0MB")
					.format(Integer.parseInt(maxSize) / 1024 / 1024);
		}
		return null;
	}

    /**
     * 校验文件类型是否合法
     */
	public String fileTypeCheck(String fileName, String allowedType) {
		boolean result = false;
		if (allowedType != null) {
			String[] types = allowedType.split(",");
			for (String type : types) {
				if (fileName.toLowerCase().endsWith(type)) {
					result = true;
					break;
				}
			}
		}
		if (!result) {
			return RtnCodeConstant.RTN_CODE_FILE_NOT_ALLOWED_ERROR;
		}
		return RtnCodeConstant.RTN_CODE_SUCCESS;
	}

    /**
     * 根据文件类型获取配置的存储目录
     */
    public String getFolder() throws ServiceException {
		String configKey = DBConstant.SYS_CONFIG_UPLOAD_FILE_SAVE_TEMP_PATH;
		String path = this.getClass().getClassLoader().getResource("/").getPath().replace("/WEB-INF/classes", "") + querySysConfigById(configKey) + File.separator;
		File tmpDir = new File(path);
		if (!tmpDir.exists()) {
		    try {
		    	FileUtils.forceMkdir(tmpDir);
		    } catch (IOException e) {
		    	logger.error("新建临时目录失败:{}", tmpDir);
		    	// e.printStackTrace();
		    }
		}
		return path;
    }

    /**
     * 根据全文件名 获取 原始文件名
     */
	public String getShortName(String fullName) {
		return fullName.substring(0, fullName.length() - 37);
	}

    /**
     * 生成唯一性文件名 name.txt.uuid{36}
     */

    public String getUniqueName(String fileName) {
		fileName = fileName.replaceAll("%", "0/0").replaceAll("'", "‘");
//		String part = fileName.substring(0, fileName.lastIndexOf("."));
		String ext = fileName.substring(fileName.lastIndexOf("."));
//		return  part + "_" + UUID.randomUUID().toString() + ext;
		return UUID.randomUUID().toString() + ext;
    }

    public Map getFileName(String fileCode) throws ServiceException {
		String rspCode = "";
		String rspMsg = "";
		Map fileMap = new HashMap();
		try {
			fileMap.put("filePath", getFolder() + fileCode);
			fileMap.put("fileName", getShortName(fileCode));
		} catch (Exception e) {
		    rspCode = RtnCodeConstant.RTN_CODE_UNKNOW_ERROR;
		    rspMsg = msgSourceAdapter.getMessage(rspCode);
		    throw new ServiceException(rspCode, rspMsg, e);
		}
		return fileMap;
    }

    public InputStream getDowloadFile(String fileCode) throws ServiceException {
		String rspCode = "";
		String rspMsg = "";
		try {
		    String filePath = getFileName(fileCode).get("filePath").toString();
		    File f = new File(filePath);
		    if (!f.exists() || !f.isFile()) {
				rspCode = RtnCodeConstant.RTN_CODE_FILE_DOWNLOAD_NO_FILE;
				rspMsg = msgSourceAdapter.getMessage(rspCode, new Object[] { getFileName(fileCode).get("fileName").toString() });
				throw new ServiceException(rspCode, rspMsg);
		    }
		    InputStream is = null;
		    ByteArrayOutputStream out = null;
		    FileInputStream fis = null;
		    try {
				fis = new FileInputStream(f);
				out = new ByteArrayOutputStream(1024);
				byte[] fByte = new byte[1024];
				int len = -1;
				while ((len = fis.read(fByte)) != -1) {
				    out.write(fByte, 0, len);
				}
				byte[] fileByte = out.toByteArray();
				is = new ByteArrayInputStream(fileByte);
		    } catch (Exception e) {
				rspCode = RtnCodeConstant.RTN_CODE_UNKNOW_ERROR;
				rspMsg = msgSourceAdapter.getMessage(rspCode);
				throw new ServiceException(rspCode, rspMsg, e);
		    } finally {
				if (null != out) {
				    try {
					out.close();
				    } catch (Exception e) {
				    }
				}
				if (null != fis) {
				    try {
				    	fis.close();
				    } catch (Exception e) {
				    }
				}
		    }
		    return is;
		} catch (ServiceException e) {
		    rspCode = e.getRspCode();
		    rspMsg = e.getRspMsg();
		    throw new ServiceException(rspCode, rspMsg, e);
		} catch (Exception e) {
		    rspCode = RtnCodeConstant.RTN_CODE_UNKNOW_ERROR;
		    rspMsg = msgSourceAdapter.getMessage(rspCode);
		    throw new ServiceException(rspCode, rspMsg, e);
		}
    }

}
